package hn.sigit.view;

import hn.sigit.dao.SigitDAO;
import hn.sigit.logic.general.ResourceBundleHelper;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.el.ELContext;
import javax.el.ExpressionFactory;
import javax.el.MethodExpression;
import javax.el.ValueExpression;
import javax.faces.application.Application;
import javax.faces.context.FacesContext;

import org.jboss.seam.annotations.In;

public abstract class MantHelper<E> implements Serializable {
	private static final long serialVersionUID = 1L;
	protected final List<E> blankList = new ArrayList<E>();

	protected List<E> entityList;
	protected E selected;
	protected boolean adding;
	protected boolean editing;
	protected boolean selecting;
	protected String searchSelector;
	protected String searchText;
	
	private boolean addingToList;
	private String addToListMethod;
	private String reRenderComponents;
	
	private String returnValueField;
	
	
	@In
	private MantUISettingsHelper mantUISettingsHelper;
	
	@In(create=true)
	protected ResourceBundleHelper resBundle;
	
	
	public List<E> getEntityList() {
		if (entityList == null) {
			entityList = new ArrayList<E>();
		}
		return entityList;
	}
	public void setEntityList(List<E> entityList) {
		this.entityList = entityList;
	}
	
	public String addNew() {
		editing = true;
		adding = true;

		return null;
	}
	
	public String edit(E e) {
		setSelected(e);
		editing = true;
		adding = false;
		
		return null;
	}
	
	public String view(E e) {
		setSelected(e);
		editing = false;
		adding = false;
		
		return null;
	}
	
	public String delete(E e) {
		SigitDAO.delete(e);
		entityList.remove(e);
		
		return null;
	}
	
	public String select(E e) {
		setSelected(e);
		doSelection();
		
		return null;
	}
	public String saveSelected() {
		SigitDAO.save(getSelected());
		if (adding) {
			getEntityList().clear();
			getEntityList().add(getSelected());
		}
		
		return null;
	}
	public abstract String quickSearch();
	
	
	public E getSelected() {
		return selected;
	}
	public void setSelected(E selected) {
		this.selected = selected;
	}
	
	
	public boolean isAdding() {
		return adding;
	}
	public boolean isEditing() {
		return editing;
	}
	
	public boolean isSelecting() {
		return selecting;
	}
	public void setSelecting(boolean selecting) {
		this.selecting = selecting;
	}
	
	public String getSearchSelector() {
		return searchSelector;
	}
	public void setSearchSelector(String searchSelector) {
		this.searchSelector = searchSelector;
	}
	
	public String getSearchText() {
		return searchText;
	}
	public void setSearchText(String searchText) {
		this.searchText = searchText;
	}
	
	public boolean isAddingToList() {
		return addingToList;
	}
	public void setAddingToList(boolean addingToList) {
		this.addingToList = addingToList;
	}
	
	public String getAddToListMethod() {
		return addToListMethod;
	}
	public void setAddToListMethod(String addToListMethod) {
		this.addToListMethod = addToListMethod;
	}
	
	public String getReRenderComponents() {
		return reRenderComponents;
	}
	public void setReRenderComponents(String reRenderComponents) {
		this.reRenderComponents = reRenderComponents;
	}
	
	public String getReturnValueField() {
		return returnValueField;
	}
	public void setReturnValueField(String returnValueField) {
		this.returnValueField = returnValueField;
	}
	
	public MantUISettingsHelper getMantUISettingsHelper() {
		return mantUISettingsHelper;
	}
	
	protected void doSelection() {
		doSelection(new String[] { returnValueField },
				new Object[] { getSelected() },
				new Class<?>[] { getSelected().getClass() });
	}
	protected void doSelection(String[] fieldNames, Object[] fieldValues, Class<?>[] classes) {
		Application app = FacesContext.getCurrentInstance().getApplication();
		ExpressionFactory exprFactory = app.getExpressionFactory();
		ELContext elCtx = FacesContext.getCurrentInstance().getELContext();
		ValueExpression ve;
		MethodExpression me;
		
		for (int i = 0; i < fieldNames.length; i++) {
			if (fieldNames[i] != null) {
				ve = exprFactory.createValueExpression(elCtx, "#{" + fieldNames[i] + "}", classes[i]);
				ve.setValue(elCtx, fieldValues[i]);
			}
		}
		if (addingToList && addToListMethod != null) {
			//third parameter is set to null meaning that we do not care for the
			//result type... and no expected parameters for fourth parameter,
			//however we can not use null for this argument
			me = exprFactory.createMethodExpression(elCtx, "#{" + addToListMethod + "}", null, new Class[] {});
			me.invoke(elCtx, null);
		}
	}
	
	protected List<E> wrapSingle(E ep) {
		List<E> epList = new ArrayList<E>();
		if (ep != null)
			epList.add(ep);
		
		return epList;
	}

}
